import {_decorator, Color, Component, Graphics, instantiate, Label, Node, Prefab, Vec3} from 'cc';
import {lobby} from "db://assets/script/lobby";
import {PropDesc} from "db://assets/script/game/mainui/props/prop-desc";

const {ccclass, property, executeInEditMode} = _decorator;

@ccclass('RadarChart')
@executeInEditMode
export class RadarChart extends Component {

    @property([Number])
    dataValues: number[] = [0.8, 0.7, 0.9, 0.6, 0.8]; // 五维数据，范围0-1

    growthPoint: Map<number, number> = new Map();

    @property([String])
    dimensionNames: string[] = ['攻击', '防御', '敏捷', '智力', '幸运']; // 维度名称

    @property
    maxRadius: number = 100; // 雷达图最大半径

    @property
    labelOffset: number = 30; // 标签偏移量

    @property(Color)
    gridColor: Color = new Color(66, 97, 142, 255); // 网格颜色

    @property(Color)
    dataFillColor: Color = new Color(51, 135, 185, 127); // 数据填充颜色

    @property(Color)
    dataLineColor: Color = new Color(66, 97, 142, 255); // 数据线颜色

    @property(Color)
    labelColor: Color = new Color(255, 255, 255, 255); // 标签颜色

    @property
    fontSize: number = 20; // 字体大小

    @property(Prefab)
    tipsPrefab!: Prefab;

    private labelNodes: Node[] = []; // 存储标签节点

    start() {
        this.drawRadarChart();
        this.node.on(Node.EventType.TOUCH_END, this.showGrowthPoint, this)
    }

    onDestroy() {
        // 清理标签节点
        this.clearLabels();
        this.node.off(Node.EventType.TOUCH_END, this.showGrowthPoint, this)
    }

    drawRadarChart() {
        const graphics = this.getComponent(Graphics)!;
        graphics.clear();

        // 清理旧标签
        this.clearLabels();

        // 绘制雷达图网格
        this.drawGrid(graphics);

        // 绘制数据区域
        this.drawDataArea(graphics);

        // 添加维度标签
        this.addDimensionLabels();
    }

    // 绘制雷达图网格
    drawGrid(graphics: Graphics) {
        const dimensions = this.dataValues.length;
        const angleOffset = (Math.PI * 2) / dimensions;

        // 绘制同心多边形网格
        const gridCount = 4; // 网格层数
        graphics.lineWidth = 5;

        for (let layer = 0; layer < gridCount; layer++) {
            const radius = this.maxRadius * (1 - layer / gridCount);
            graphics.strokeColor = new Color(
                this.gridColor.r,
                this.gridColor.g,
                this.gridColor.b,
                this.gridColor.a * (1 - layer * 0.25)
            );

            // 绘制正五边形
            for (let i = 0; i <= dimensions; i++) {
                const angle = i * angleOffset - Math.PI / 2;
                const x = radius * Math.cos(angle);
                const y = radius * Math.sin(angle);

                if (i === 0) {
                    graphics.moveTo(x, y);
                } else {
                    graphics.lineTo(x, y);
                }
            }
            graphics.stroke();
        }

        // 绘制轴线
        graphics.lineWidth = 2;
        graphics.strokeColor = this.gridColor;
        for (let i = 0; i < dimensions; i++) {
            const angle = i * angleOffset - Math.PI / 2;
            const x = this.maxRadius * Math.cos(angle);
            const y = this.maxRadius * Math.sin(angle);

            graphics.moveTo(0, 0);
            graphics.lineTo(x, y);
        }
        graphics.stroke();
    }

    // 绘制数据区域
    drawDataArea(graphics: Graphics) {
        const dimensions = this.dataValues.length;
        const angleOffset = (Math.PI * 2) / dimensions;

        graphics.lineWidth = 3;
        graphics.strokeColor = this.dataLineColor;
        graphics.fillColor = this.dataFillColor;

        // 计算数据点位置
        for (let i = 0; i < dimensions; i++) {
            const angle = i * angleOffset - Math.PI / 2;
            const radius = this.maxRadius * this.dataValues[i];
            const x = radius * Math.cos(angle);
            const y = radius * Math.sin(angle);

            if (i === 0) {
                graphics.moveTo(x, y);
            } else {
                graphics.lineTo(x, y);
            }
        }
        graphics.close();
        graphics.fill();
        graphics.stroke();
    }

    // 添加维度标签
    addDimensionLabels() {
        const dimensions = this.dimensionNames.length;
        const angleOffset = (Math.PI * 2) / dimensions;

        for (let i = 0; i < dimensions; i++) {
            const angle = i * angleOffset - Math.PI / 2;

            // 计算标签位置（在最大半径基础上再偏移一定距离）
            const labelRadius = this.maxRadius + this.labelOffset;
            const x = labelRadius * Math.cos(angle);
            const y = labelRadius * Math.sin(angle);

            // 创建标签节点
            const labelNode = new Node(`Label_${i}`);
            const label = labelNode.addComponent(Label);

            label.enableOutline = true
            // 设置标签属性
            label.string = this.dimensionNames[i];
            // label.color = this.labelColor;
            label.fontSize = this.fontSize;
            label.lineHeight = this.fontSize;

            // 根据位置调整文本对齐方式
            if (Math.abs(Math.cos(angle)) < 0.3) {
                // 接近垂直方向，水平居中
                label.horizontalAlign = Label.HorizontalAlign.CENTER;
            } else if (Math.cos(angle) > 0) {
                // 右侧，左对齐
                label.horizontalAlign = Label.HorizontalAlign.LEFT;
            } else {
                // 左侧，右对齐
                label.horizontalAlign = Label.HorizontalAlign.RIGHT;
            }

            // 根据位置调整文本垂直对齐
            if (Math.abs(Math.sin(angle)) < 0.3) {
                // 接近水平方向，垂直居中
                label.verticalAlign = Label.VerticalAlign.CENTER;
            } else if (Math.sin(angle) > 0) {
                // 上方，底部对齐
                label.verticalAlign = Label.VerticalAlign.BOTTOM;
            } else {
                // 下方，顶部对齐
                label.verticalAlign = Label.VerticalAlign.TOP;
            }

            // 添加到当前节点下
            this.node.addChild(labelNode);

            // 设置节点位置
            labelNode.setPosition(new Vec3(x, y, 0));
            labelNode.layer = this.node.layer

            // 保存引用以便后续清理
            this.labelNodes.push(labelNode);
        }
    }

    // 清理标签节点
    clearLabels() {
        this.labelNodes.forEach(node => {
            if (node && node.isValid) {
                node.removeFromParent();
                node.destroy();
            }
        });
        this.labelNodes = [];
        this.node.destroyAllChildren()
    }

    // 更新数据的方法
    updateData(growthPoint: Map<number, number>, newData: number[], newNames?: string[]) {
        if (newData.length !== 5) {
            console.error('雷达图需要5个数据值');
            return;
        }

        this.dataValues = newData;
        this.growthPoint = growthPoint;

        if (newNames && newNames.length === 5) {
            this.dimensionNames = newNames;
        }

        this.drawRadarChart();
    }

    showGrowthPoint() {
        const tn = instantiate(this.tipsPrefab)
        lobby.instance.gui.addChild(tn)
        const propDesc = tn.getComponent(PropDesc)!
        propDesc.initGrowthPoint(this.node, this.growthPoint)
    }

    // 在属性面板中更改时刷新
    protected onPropertyChange() {
        this.drawRadarChart();
    }
}